//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
namespace LargoBase.Streams {
using LargoBase.Abstract;
using LargoBase.Enums;
using LargoBase.Music;
using LargoBase.Structures;
using System.Diagnostics.Contracts;
using System.Linq;
///
/// Harmonic Provider.
///
public class HarmonicProvider {
#region Fields
///
/// The variety
///
private readonly StructuralVariety variety;
#endregion
#region Constructor
///
/// Initializes a new instance of the class.
///
/// The given header.
/// The modality.
public HarmonicProvider(MusicalHeader givenHeader, HarmonicModality modality) {
Contract.Requires(modality != null);
this.Header = givenHeader;
this.variety = new StructuralVariety(this.Header.System.HarmonicSystem) {
VarType = GenStructuralVarietyType.BinarySubstructuresOfModality,
Modality = modality,
LimitCount = 1000
};
this.variety.Generate();
var structures = (from v in this.variety.StructList where v.Level == 3 select v).ToList();
foreach (var s in structures) {
s.Modality = modality;
s.DetermineBehaviorInModality();
}
this.variety.SetStructList(structures);
}
#endregion
#region Properties
///
/// Gets or sets the header.
///
///
/// The header.
///
public MusicalHeader Header { get; set; }
#endregion
#region String representation
/// String representation of the object.
/// Returns value.
public override string ToString() {
return "Harmonic Provider";
}
#endregion
#region Public methods
///
/// Gets the harmonic stream.
///
/// The given header.
/// The rhythmic stream.
/// The energy stream.
///
/// Returns value.
///
public HarmonicStream GetHarmonicStream(MusicalHeader givenHeader, RhythmicStream rhythmicStream, HarmonicEnergyStream energyStream) {
if (givenHeader.Clone() is MusicalHeader header)
{
header.Name = SupportCommon.DateTimeIdentifier;
header.FileName = "Generated";
}
var stream = new HarmonicStream(givenHeader);
foreach (var ebar in energyStream.EnergyBars) {
var structure = rhythmicStream.StructureInBar(ebar.BarNumber);
if (structure == null) {
continue;
}
var request = HarmonicProvider.GetRequest(ebar); //// ebar.HarmonicFlow, ebar.IsConsonant
var hbar = this.PrepareHarmonicBar(structure, request);
if (hbar == null) {
continue;
}
hbar.BarNumber = ebar.BarNumber;
stream.HarmonicBars.Add(hbar);
}
return stream;
}
#endregion
#region Private static methods
///
/// Gets the request.
///
/// The energy bar.
///
/// Returns value.
///
private static GeneralRequest GetRequest(HarmonicEnergyBar energyBar) {
var request = new GeneralRequest();
var item = new GeneralRequestItem(GenProperty.Consonance, 1.0f, (float)energyBar.HarmonicConsonance);
request.Items.Add(GenProperty.Consonance, item);
item = new GeneralRequestItem(GenProperty.Potential, 1.0f, (float)energyBar.HarmonicPotential);
request.Items.Add(GenProperty.Potential, item);
item = new GeneralRequestItem(GenProperty.RelatedContinuity, 1.0f, 100);
request.Items.Add(GenProperty.RelatedContinuity, item);
return request;
}
#endregion
#region Private methods
///
/// Prepares the harmonic bar.
///
/// The structure.
/// The request.
///
/// Returns value.
///
private HarmonicBar PrepareHarmonicBar(RhythmicStructure structure, GeneralRequest request) {
if (structure == null) {
return null;
}
if (this.variety == null || !this.variety.StructList.Any()) {
return null;
}
var rs = structure.RhythmicSystem;
var shape = new RhythmicShape(rs.Order, structure);
var harmonicBar = new HarmonicBar(1, 0) {
RhythmicStructure = structure
};
for (byte level = 0; level < shape.Level; level++) {
var place = shape.Places[level];
var distance = shape.DistanceAtLevel(level);
//// var request = HarmonicStream.GetRequest(rs.Order, distance);
var hs = this.variety.OptimalNextStructForRequest(request);
if (hs == null) {
continue;
}
foreach (var hstr in this.variety.StructList) {
hstr.SetPreviousStruct(hs);
}
///// barMetric.On(tick);
hs.BitFrom = place;
hs.Length = distance;
hs.HarmonicModality = (HarmonicModality)this.variety.Modality;
harmonicBar.AddStructure(hs);
}
harmonicBar.HarmonicModality = (HarmonicModality)this.variety.Modality;
//// barMetric.DetermineLevel();
//// string barMetricCode = barMetric.GetStructuralCode();
shape.DetermineLevel();
var barMetricCode = shape.GetStructuralCode;
harmonicBar.SetBarMetricCode(barMetricCode);
return harmonicBar;
}
#endregion
}
}